#ifndef DockWidgetH
#define DockWidgetH
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
/// \file   DockWidget.h
/// \author Uwe Kindler
/// \date   26.02.2017
/// \brief  Declaration of CDockWidget class
//============================================================================


//============================================================================
//                                   INCLUDES
//============================================================================
#include <QFrame>

#include "ads_globals.h"

QT_FORWARD_DECLARE_CLASS(QToolBar)
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)

namespace ads
{
struct DockWidgetPrivate;
class CDockWidgetTab;
class CDockManager;
class CDockContainerWidget;
class CDockAreaWidget;
class DockContainerWidgetPrivate;
class CFloatingDockContainer;
class CAutoHideTab;
class CAutoHideDockContainer;
class CAutoHideSideBar;

/**
 * CDockWidget类提供了一个可以在CDockManager中停靠的小部件，
 * 或者可以作为桌面上的顶级窗口浮动。
 */
class ADS_EXPORT CDockWidget : public QFrame
{
    Q_OBJECT

private:
    DockWidgetPrivate* d; ///< 私有数据 (pimpl)
    friend struct DockWidgetPrivate;

// 设置工具栏图标大小根据浮动状态调整
void setToolbarFloatingStyle(bool topLevel);

protected:
// 友元类声明
friend class CDockContainerWidget;
friend class CDockAreaWidget;
friend class CFloatingDockContainer;
friend class CDockManager;
friend struct DockManagerPrivate;
friend class DockContainerWidgetPrivate;
friend class CDockAreaTabBar;
friend class CDockWidgetTab;
friend struct DockWidgetTabPrivate;
friend struct DockAreaTitleBarPrivate;
friend class CAutoHideDockContainer;
friend CAutoHideSideBar;

// 分配管理此dock widget的dock manager
void setDockManager(CDockManager* DockManager);

// 如果此dock widget被插入到dock area中，通过此函数将dock area注册到此widget上
// 如果dock widget从dock area中移除，将会以nullptr值调用此函数
void setDockArea(CDockAreaWidget* DockArea);

// 此函数在不发出任何信号的情况下更改toggle view action
void setToggleViewActionChecked(bool Checked);

// 将状态保存到给定的流中
void saveState(QXmlStreamWriter& Stream) const;

// 这是一个帮助函数，用于将此widget标记为未分配
// 在调用恢复函数时，可能会发生保存的状态包含比当前可用的dock widget更少的情况
// 所有数据不包含在保存的状态中的小部件，在恢复过程之后都会被标记为未分配
// 如果用户显示一个未分配的dock widget，将创建一个浮动窗口来接收dock widget
void flagAsUnassigned();

// 调用此函数发出topLevelChanged()信号并更新dock area工具栏的可见性
static void emitTopLevelEventForWidget(CDockWidget* TopLevelDockWidget, bool Floating);

// 使用此函数发出top level changed事件
// 永远不要使用emit topLevelChanged()，始终使用此函数，因为它只在浮动状态真正改变时发出信号
void emitTopLevelChanged(bool Floating);

// 内部函数用于在恢复保存的停靠状态时修改关闭状态
void setClosedState(bool Closed);

// 内部的toggle view函数，不检查小部件是否已经处于给定状态
void toggleViewInternal(bool Open);

// 内部关闭dock widget实现
// 如果dock widget已关闭或隐藏，函数返回true
bool closeDockWidgetInternal(bool ForceClose = false);

public:
    using Super = QFrame;

    // 定义 Dock Widget 的不同特性
    enum DockWidgetFeature
    {
        DockWidgetClosable = 0x001,///< Dock Widget 有关闭按钮
        DockWidgetMovable = 0x002,///< Dock Widget 可移动，可以移动到当前 Dock 容器的新位置
        DockWidgetFloatable = 0x004,///< Dock Widget 可以拖动到浮动窗口中
        DockWidgetDeleteOnClose = 0x008, ///< 关闭 Dock Widget 时删除它
        CustomCloseHandling = 0x010, ///< 单击关闭按钮不会关闭 Dock Widget，而是发出 closeRequested() 信号
        DockWidgetFocusable = 0x020, ///< 如果启用，Dock Widget 可以获得焦点高亮
        DockWidgetForceCloseWithArea = 0x040, ///< 当托管 Dock Widget 的 Dock Area 关闭时，Dock Widget 也会关闭
        NoTab = 0x080, ///< 如果设置了此标志，Dock Widget 标签将永远不会显示
        DeleteContentOnClose = 0x100, ///< 仅在关闭时删除包含的小部件，保持 Dock Widget 不变且保持在原位。如果设置了小部件工厂，则在显示时尝试重新构建内容小部件。
        DockWidgetPinnable = 0x200, ///< Dock Widget 可以固定并添加到自动隐藏的 Dock 容器中
        DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable | DockWidgetPinnable,
        AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
        DockWidgetAlwaysCloseAndDelete = DockWidgetForceCloseWithArea | DockWidgetDeleteOnClose,
        NoDockWidgetFeatures = 0x000
    };

    Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)

    // 定义 Dock Widget 的不同状态
    enum eState
    {
        StateHidden, ///< 隐藏状态
        StateDocked, ///< 停靠状态
        StateFloating ///< 浮动状态
    };

    /**
     * 设置 Dock Widget 的小部件为 widget。
     * InsertMode 定义了如何将小部件插入 Dock Widget。
     * Dock Widget 的内容应该可以调整大小到非常小的尺寸，以防止阻塞调整大小。
     * 为了确保 Dock Widget 可以被很好地调整大小，最好将内容小部件+小部件插入滚动区域，
     * 或者提供一个已经是滚动区域或包含滚动区域的小部件。
     * 如果 InsertMode 是 AutoScrollArea，则 Dock Widget 尝试自动检测如何插入给定的小部件。
     * 如果小部件派生自 QScrollArea（即 QAbstractItemView），则直接插入小部件。
     * 如果给定的小部件不是滚动区域，则将小部件插入滚动区域中。
     * 若要强制插入滚动区域，也可以使用 InsertMode ForceScrollArea。
     * 若要防止插入滚动区域，可以使用 InsertMode ForceNoScrollArea。
     */
    enum eInsertMode
    {
        AutoScrollArea, ///< 自动检测插入滚动区域
        ForceScrollArea, ///< 强制插入滚动区域
        ForceNoScrollArea ///< 防止插入滚动区域
    };

    /**
     * minimumSizeHint() 函数返回的 minimumSizeHint() 的模式。
     * 为了确保 Dock Widget 不会阻塞调整大小，Dock Widget 重新实现了 minimumSizeHint() 函数，
     * 返回一个非常小的最小尺寸提示。如果您希望遵循内容小部件的 minimumSizeHint()，
     * 则将 minimumSizeHintMode() 设置为 MinimumSizeHintFromContent。
     * 如果要使用内容小部件或 Dock Widget 的 minimumSize() 值，可以使用
     * MinimumSizeHintFromDockWidgetMinimumSize 或 MinimumSizeHintFromContentMinimumSize 模式。
     */
    enum eMinimumSizeHintMode
    {
        MinimumSizeHintFromDockWidget, ///< 从 Dock Widget 获取最小尺寸提示
        MinimumSizeHintFromContent, ///< 从内容小部件获取最小尺寸提示
        MinimumSizeHintFromDockWidgetMinimumSize, ///< 从 Dock Widget 的最小尺寸获取最小尺寸提示
        MinimumSizeHintFromContentMinimumSize, ///< 从内容小部件的最小尺寸获取最小尺寸提示
    };

    /**
     * 切换视图动作的行为模式。
     * 如果模式为 ActionModeToggle，则切换视图动作是可选中的动作，用于显示/隐藏 Dock Widget。
     * 如果模式为 ActionModeShow，则动作不可选中，并且单击后始终显示 Dock Widget。
     * 如果模式为 ActionModeShow，则用户只能使用关闭按钮关闭 Dock Widget。
     */
    enum eToggleViewActionMode
    {
        ActionModeToggle, //!< 切换模式
        ActionModeShow   //!< 显示模式
    };


    /**
     * 构造函数，创建一个具有给定标题的dock widget
     * 标题是在dock widget浮动时显示在窗口标题栏中的文本，如果dock widget被tab化，标题也显示在标题栏或者tab上
     * dock widget的对象名称也被设置为标题。对象名称是dock manager正确保存和恢复dock widget状态所必需的。这意味着标题需要是唯一的。
     * 如果您的标题不是唯一的，或者在运行时想要更改标题，需要在构造后调用setObjectName()来显式设置唯一的对象名称。
     * 使用layoutFlags来配置dock widget的布局。
     */
    CDockWidget(const QString &title, QWidget* parent = 0);
    
    /**
     * 虚析构函数
     */
    virtual ~CDockWidget();
    
    /**
     * 返回一个固定的最小大小提示，或者如果最小大小提示模式是MinimumSizeHintFromContent，则返回内容widget的大小提示
     */
    virtual QSize minimumSizeHint() const override;
    
    /**
     * 设置dock widget的widget为给定的widget。
     * InsertMode定义了如何将widget插入dock widget中。
     * dock widget的内容应该可以调整大小到非常小的尺寸，以防止dock widget阻塞调整大小。为了确保dock widget可以非常好地调整大小，最好将内容+widget插入滚动区域，或者提供一个已经是滚动区域或包含滚动区域的widget。
     * 如果InsertMode是AutoScrollArea，则DockWidget尝试自动检测如何插入给定的widget。如果widget派生自QScrollArea（即QAbstractItemView），则直接插入该widget。如果给定的widget不是滚动区域，则将widget插入到滚动区域中。
     * 您还可以提供InsertMode ForceScrollArea来强制插入滚动区域，或者提供InsertMode ForceNoScrollArea来阻止插入滚动区域。
     */
    void setWidget(QWidget* widget, eInsertMode InsertMode = AutoScrollArea);
	
    /**
	 * 仅在设置了特性标志DeleteContentOnClose时使用。
	 * 使用该标志并设置一个widget工厂，可以在保留下次显示widget位置的同时释放应用程序的widget资源，与标志DockWidgetDeleteOnClose不同，后者删除dock widget本身。由于我们保留了dock widget，ADS的所有常规功能都可以正常工作，包括保存和恢复dock系统的状态以及使用透视图。
	 */
	using FactoryFunc = std::function<QWidget*(QWidget*)>;
	void setWidgetFactory(FactoryFunc createWidget, eInsertMode InsertMode = AutoScrollArea);
    
    /**
     * 从dock中移除widget并将所有权还给调用者
     */
    QWidget* takeWidget();
    
    /**
     * 返回dock widget的widget。如果widget未设置，则返回零。
     */
    QWidget* widget() const;
    
    /**
     * 返回显示在dock区域标题栏中的此dock widget的tab widget
     */
    CDockWidgetTab* tabWidget() const;
    
    /**
     * 设置dock widget是否可移动、可关闭和可浮动。
     */
    void setFeatures(DockWidgetFeatures features);

    将下面的代码更易读，必要时添加注释，并提供重写的代码，其中包含```后跟一个新行，请用简体中文回复

/**
 * 如果 on 为 true，则设置此停靠窗口的功能标志；否则清除标志。
 */
void setFeature(DockWidgetFeature flag, bool on);

/**
 * 此属性指示停靠窗口是否可移动、可关闭和可浮动。
 * 默认情况下，此属性设置为 DockWidgetClosable、DockWidgetMovable 和 DockWidgetFloatable 的组合。
 */
DockWidgetFeatures features() const;

/**
 * 返回管理停靠窗口的停靠管理器，如果该窗口尚未分配给任何停靠管理器，则返回 0
 */
CDockManager* dockManager() const;

/**
 * 返回此停靠区域窗口所属的停靠容器窗口，如果此停靠窗口尚未停靠，则返回 0
 */
CDockContainerWidget* dockContainer() const;

/**
 * 如果 isFloating() 为 true，则返回浮动 DockContainer，如果此停靠窗口未浮动，则返回 nullptr。
 */
CFloatingDockContainer* floatingDockContainer() const;

/**
 * 返回此停靠窗口所属的停靠区域窗口，如果此停靠窗口尚未停靠，则返回 0
 */
CDockAreaWidget* dockAreaWidget() const;

/**
 * 如果此停靠窗口位于自动隐藏容器中，则返回其侧边选项卡窗口。如果不在自动隐藏容器中，则此函数返回 nullptr。
 */
CAutoHideTab* sideTabWidget() const;

/**
 * 如果此停靠窗口是自动隐藏容器，则分配一个侧边选项卡窗口
 */
void setSideTabWidget(CAutoHideTab* SideTab) const;

/**
 * 如果此停靠窗口在自动隐藏容器中，则返回 true
 */
bool isAutoHide() const;

/**
 * 返回此停靠窗口的自动隐藏停靠容器，如果没有，则返回 0
 */
CAutoHideDockContainer* autoHideDockContainer() const;

/**
 * 返回自动隐藏侧边栏位置或 SideBarNone（如果不是自动隐藏停靠窗口）
 */
SideBarLocation autoHideLocation() const;

/**
 * 此属性指示停靠窗口是否浮动。
 * 只有在浮动容器中只有一个窗口时，停靠窗口才是浮动的。如果浮动容器中有多个停靠窗口，则所有停靠窗口都是停靠的，而不是浮动的。
 */
bool isFloating() const;

/**
 * 如果此停靠窗口在浮动窗口中，则此函数返回 true。如果停靠窗口浮动，则返回 true，如果停靠窗口停靠在浮动容器中，则也返回 true。
 */
bool isInFloatingContainer() const;

/**
 * 如果此停靠窗口已关闭，则返回 true。
 */
bool isClosed() const;

/**
 * 返回可检查的操作，可用于显示或关闭此停靠窗口。
 * 操作的文本设置为停靠窗口的窗口标题。
 */
QAction* toggleViewAction() const;

/**
 * 配置切换视图操作的行为。
 * 有关详细说明，请参见 eToggleViewActionMode
 */
void setToggleViewActionMode(eToggleViewActionMode Mode);

/**
 * 设置此停靠窗口的功能标志
 * @param flag 功能标志
 * @param on 是否开启
 */
void setFeature(DockWidgetFeature flag, bool on);

/**
 * 获取停靠窗口的功能标志
 * @return 功能标志
 */
DockWidgetFeatures features() const;

/**
 * 获取管理停靠窗口的停靠管理器
 * @return 停靠管理器
 */
CDockManager* dockManager() const;

/**
 * 获取停靠窗口所属的停靠容器窗口
 * @return 停靠容器窗口
 */
CDockContainerWidget* dockContainer() const;

/**
 * 获取浮动停靠窗口所在的浮动容器
 * @return 浮动容器
 */
CFloatingDockContainer* floatingDockContainer() const;

/**
 * 获取停靠窗口所属的停靠区域窗口
 * @return 停靠区域窗口
 */
CDockAreaWidget* dockAreaWidget() const;

/**
 * 获取自动隐藏停靠窗口的侧边选项卡窗口
 * @return 侧边选项卡窗口
 */
CAutoHideTab* sideTabWidget() const;

/**
 * 分配自动隐藏停靠窗口的侧边选项卡窗口
 * @param SideTab 侧边选项卡窗口
 */
void setSideTabWidget(CAutoHideTab* SideTab) const;

/**
 * 判断停靠窗口是否在自动隐藏容器中
 * @return 是否在自动隐藏容器中
 */
bool isAutoHide() const;

/**
 * 获取自动隐藏停靠窗口的停靠容器
 * @return 停靠容器
 */
CAutoHideDockContainer* autoHideDockContainer() const;

/**
 * 获取自动隐藏停靠窗口的侧边栏位置
 * @return 侧边栏位置
 */
SideBarLocation autoHideLocation() const;

/**
 * 判断停靠窗口是否浮动
 * @return 是否浮动
 */
bool isFloating() const;

/**
 * 判断停靠窗口是否在浮动容器中
 * @return 是否在浮动容器中
 */
bool isInFloatingContainer() const;

/**
 * 判断停靠窗口是否关闭
 * @return 是否关闭
 */
bool isClosed() const;

/**
 * 获取可检查的操作，用于显示或关闭停靠窗口
 * @return 操作
 */
QAction* toggleViewAction() const;

/**
 * 配置切换视图操作的行为
 * @param Mode 切换视图操作的行为
 */
void setToggleViewActionMode(eToggleViewActionMode Mode);

    /**
 * 设置返回最小大小提示的最小大小提示模式
 * \see eMinimumSizeHintMode 详细描述
 */
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);

/**
 * 获取由setMinimumSizeHintMode配置的最小大小提示模式
 */
eMinimumSizeHintMode minimumSizeHintMode() const;

/**
 * 如果dock窗口被设置为其dock管理器的中央窗口，则返回true
 */
bool isCentralWidget() const;

/**
 * 设置在选项卡和切换视图中显示的dock窗口图标
 */
void setIcon(const QIcon& Icon);

/**
 * 返回分配给dock窗口的图标
 */
QIcon icon() const;

/**
 * 返回dock窗口的顶部工具栏
 * 如果没有分配工具栏，则返回nullptr。要获得有效的工具栏，您可以通过createDefaultToolBar()函数创建一个默认的空工具栏，或者通过setToolBar()分配自定义工具栏。
 */
QToolBar* toolBar() const;

/**
 * 如果要使用默认的顶部工具栏，请调用此函数创建默认工具栏。
 * 在此函数之后，toolBar()函数将返回一个有效的toolBar()对象。
 */
QToolBar* createDefaultToolBar();

/**
 * 分配在内容窗口上方显示的新工具栏。
 * dock窗口将成为工具栏的所有者，并在销毁时删除它。
 */
void setToolBar(QToolBar* ToolBar);

/**
 * 设置给定dock窗口状态的工具按钮样式。
 * 可以根据状态切换工具按钮样式。
 * 如果dock窗口浮动，则有更多的空间，可以选择需要更多空间的样式，如Qt::ToolButtonTextUnderIcon。
 * 对于停靠状态，Qt::ToolButtonIconOnly可能更好。
 */
void setToolBarStyle(Qt::ToolButtonStyle Style, eState State);

/**
 * 返回给定停靠状态的工具按钮样式。
 * \see setToolBarStyle()
 */
Qt::ToolButtonStyle toolBarStyle(eState State) const;

/**
 * 设置给定状态的工具按钮图标大小。
 * 如果dock窗口浮动，有更多的空间，可以增加图标大小。
 * 对于停靠窗口，较小的图标大小，例如16 x 16可能更好。
 */
void setToolBarIconSize(const QSize& IconSize, eState State);

/**
 * 返回给定停靠状态的图标大小。
 * \see setToolBarIconSize()
 */
QSize toolBarIconSize(eState State) const;

/**
 * 设置在此dock窗口成为活动选项卡时将显示在dock区域标题栏中的操作。
 * 不应该在标题栏中添加太多操作，因为这将减少选项卡的可用空间。如果有多个操作，只需添加一个带有菜单的操作，以在标题栏中显示弹出菜单按钮。
 */
void setTitleBarActions(QList<QAction*> actions);

/**
 * 返回一个列表，其中包含在此dock窗口成为当前窗口时将插入到dock区域标题栏中的操作。
 */
virtual QList<QAction*> titleBarActions() const;


#ifndef QT_NO_TOOLTIP
    /**
     * 设置标题栏小部件的文本工具提示
     * 和切换视图操作的工具提示
     */
    void setTabToolTip(const QString &text);
#endif

/**
 * 如果停靠窗口浮动，并且浮动停靠容器是全屏的，则返回true
 */
bool isFullScreen() const;

/**
 * 如果此停靠窗口位于包含至少2个打开的停靠窗口的停靠区域中，则返回true
 */
bool isTabbed() const;

/**
 * 如果此停靠窗口是包含它的停靠区域中的当前窗口，则返回true
 * 如果停靠区域中只有一个打开的停靠窗口，则返回true
 */
bool isCurrentTab() const;

public: // 重新实现 QFrame -----------------------------------------------

/**
 * 如果发生标题更改事件，则发出 titleChanged 信号
 */
virtual bool event(QEvent *e) override;

public Q_SLOTS:

/**
 * 此属性控制停靠窗口是打开还是关闭
 * toggleViewAction 触发此槽函数
 */
void toggleView(bool Open = true);

/**
 * 将此停靠窗口设置为其停靠区域中的当前选项卡
 * 如果停靠窗口已打开，此函数才会生效。调用此函数不会切换视图，因此如果关闭了视图，则不会发生任何操作
 */
void setAsCurrentTab();

/**
 * 将停靠窗口置于前台
 * 这意味着：
 * - 如果停靠窗口与其他停靠窗口标签化，但其标签不是当前的，则将其设置为当前的
 * - 如果停靠窗口浮动，调用 QWindow::raise()
 * 仅当停靠窗口已打开时才适用。如果已关闭，则不会执行任何操作
 */
void raise();

/**
 * 将停靠窗口设置为浮动状态
 */
void setFloating();

/**
 * 从停靠系统中删除停靠窗口及其内容
 */
void deleteDockWidget();

/**
 * 关闭停靠窗口
 * 该函数强制关闭停靠窗口，即使对于 CustomCloseHandling 也是如此
 */
void closeDockWidget();

/**
 * 请求关闭停靠窗口
 * 对于具有默认关闭处理的 DockWidget，该函数与 closeDockWidget() 相同
 * 但如果设置了 CustomCloseHandling 标志，则该函数仅发出 closeRequested() 信号
 */
void requestCloseDockWidget();

/**
 * 以全屏模式显示小部件
 * 通常，此函数仅影响窗口。为了使接口与 QDockWidget 兼容，此函数还会将浮动停靠窗口最大化
 *
 * \note 全屏模式在 Windows 下运行良好，但在 X（Linux）下存在某些问题（不起作用）。
 * 这些问题是由 ICCCM 协议的限制造成的，该协议规定了 X11 客户端与窗口管理器之间的通信。
 * ICCCM 简单地不理解无装饰的全屏窗口的概念
 */
void showFullScreen();

/**
 * 此函数与 showFullScreen() 互补，用于恢复小部件在全屏模式下的状态
 */
void showNormal();

/**
 * 如果启用了此功能（通过 CDockManager::setAutoHideFlags(CDockManager::AutoHideFeatureEnabled)），
 * 则将停靠窗口设置为自动隐藏模式
 */
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone, int TabIndex = -1);

/**
 * 根据其当前状态，将停靠窗口切换到自动隐藏模式或反之
 */
void toggleAutoHide(SideBarLocation Location = SideBarNone);


Q_SIGNALS:
    /**
 * 停靠窗口打开或关闭时发出此信号
 */ 
void viewToggled(bool isOpen);

/**
 * 停靠窗口关闭时发出此信号
 */ 
void closed();

/**
 * 停靠窗口的窗口标题更改时发出此信号
 */ 
void titleChanged(const QString& title);

/**
 * 浮动属性更改时发出此信号。
 * 如果停靠窗口现在浮动，则 topLevel 参数为 true；
 * 否则为 false。
 */ 
void topLevelChanged(bool isTopLevel);

/**
 * 关闭请求时发出此信号
 */ 
void closeRequested();

/**
 * 停靠窗口变为可见（或不可见）时发出此信号。
 * 当小部件被隐藏或显示时，以及当它被停靠在选项卡式停靠区域中并且其选项卡被选中或取消选中时，都会发生这种情况。
 */ 
void visibilityChanged(bool isVisible);

/**
 * features 属性更改时发出此信号。
 * features 参数给出了属性的新值。
 */ 
void featuresChanged(ads::CDockWidget::DockWidgetFeatures features);
}; // class DockWidget
} // namespace ads

Q_DECLARE_OPERATORS_FOR_FLAGS(ads::CDockWidget::DockWidgetFeatures)
//-----------------------------------------------------------------------------
#endif // DockWidgetH
